﻿using System;
using System.ComponentModel;
using System.Diagnostics;

namespace Mp3Observer.Common
{
    /// <summary>
    /// Base class with INotifyPropertyChanged
    /// </summary>
    // [Serializable] (Serializable is not possible in the Silverlight Library)
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Notifiable", Justification = "ok so")]
    public abstract class Notifiable : INotifyPropertyChanged
    {
        #region Ctors

        /// <summary>
        /// Initializes a new instance of the <see cref="Notifiable"/> class. Empty ctor needed for serialization.
        /// </summary>
        protected Notifiable()
        {
        }

        #endregion

        #region Events

        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Methods

        /// <summary>
        /// Called when [property changed].
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        public void OnPropertyChanged(string propertyName)
        {
            // verify the property
            this.VerifyPropertyName(propertyName);
            // local copy, thread safe!
            var handler = this.PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }

        /// <summary>
        /// Verifies the name of the property on Debug builds.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "the method is called from wpf")]
        [Conditional("DEBUG")]
        [DebuggerStepThrough]
        private void VerifyPropertyName(string propertyName)
        {
#if !SILVERLIGHT
            if (TypeDescriptor.GetProperties(this)[propertyName] == null)
            {
                string msg = "Invalid property name: " + propertyName;
                throw new ArgumentException(msg, propertyName);
            }
#endif
        }

        #endregion
    }
}
